package main

import (
	"context"
	"flag"
	"strconv"
	"time"

	"github.com/gogf/gf/os/glog"
	"github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc"
	"github.com/opentracing/opentracing-go"
	"google.golang.org/grpc"
	"google.golang.org/grpc/balancer/roundrobin"
	"google.golang.org/grpc/resolver"

	grpc_retry "github.com/grpc-ecosystem/go-grpc-middleware/retry"
	pb "github.com/wwcd/grpc-lb/cmd/helloworld"
	"github.com/wwcd/grpc-lb/common/trace"
	grpclb "github.com/wwcd/grpc-lb/etcdv3"
)

var (
	svc        = flag.String("service", "hello_service", "service name")
	reg        = flag.String("reg", "http://192.168.0.101:2379", "register etcd address")
	jaegeraddr = flag.String("jaeger", "192.168.0.101:6831", "Jaeger address")
)

// WithTracer traces rpc calls
func WithTracer(t opentracing.Tracer) grpc.DialOption {

	return grpc.WithUnaryInterceptor(otgrpc.OpenTracingClientInterceptor(t))
}
func main() {

	flag.Parse()
	tracer, err := trace.New("search", *jaegeraddr)
	r := grpclb.NewResolver(*reg, *svc)
	resolver.Register(r)

	retryOps := []grpc_retry.CallOption{
		grpc_retry.WithMax(3),
		grpc_retry.WithPerRetryTimeout(time.Second * 5),
		grpc_retry.WithBackoff(grpc_retry.BackoffLinearWithJitter(time.Second/2, 0.2)),
	}
	retryInterceptor := grpc_retry.UnaryClientInterceptor(retryOps...)

	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	// https://github.com/grpc/grpc/blob/master/doc/naming.md
	// The gRPC client library will use the specified scheme to pick the right resolver plugin and pass it the fully qualified name string.
	conn, err := grpc.DialContext(ctx, r.Scheme()+"://authority/"+*svc, grpc.WithInsecure(),
		grpc.WithBalancerName(roundrobin.Name), grpc.WithBlock(),
		WithTracer(tracer),
		grpc.WithUnaryInterceptor(retryInterceptor),
	)
	cancel()
	if err != nil {
		panic(err)
	}

	ticker := time.NewTicker(1 * time.Millisecond)
	for _ = range ticker.C {
		// for {
		client := pb.NewGreeterClient(conn)
		_, err := client.SayHello(context.Background(), &pb.HelloRequest{Name: "world " + strconv.Itoa(2)})
		if err == nil {
			// glog.Infof("%v: Reply is %s\n", t, resp.Message)
		} else {
			glog.Errorf(" Reply is ")

		}
	}
}
